package utils

import (
	"encoding/json"
	"io/ioutil"

	"zinx/ziface"
)

/*
	存储一切有关Zinx框架的全局参数，供其他模块使用
	一些参数也可以通过 用户根据 zinx.json来配置
*/
type GlobalObj struct {
	/*
		Server
	*/
	TcpServer ziface.IServer //当前Zinx的全局Server对象
	Host      string         //当前服务器主机IP
	TcpPort   int            //当前服务器主机监听端口号
	Name      string         //当前服务器名称

	/*
		Zinx
	*/
	Version       string //当前Zinx版本号
	MaxPacketSize uint32 //当前数据包的最大值
	MaxConn       int    //当前服务器主机允许的最大链接个数

}

/*
	定义一个全局的对象
*/
var GlobalObject *GlobalObj

//读取用户的配置文件
func (g *GlobalObj) Reload() {
	data, err := ioutil.ReadFile("conf/zinx.json")
	if err != nil {
		panic(err)
		/*
					在通常情况下，向程序使用方报告错误状态的方式可以是返回一个额外的error类型值。

			但是，当遇到不可恢复的错误状态的时候，如数组访问越界、空指针引用等，这些运行时错误会引起painc异常。
			这时，上述错误处理方式显然就不适合了。反过来讲，在一般情况下，我们不应通过调用panic函数来报告普通的错误，
			而应该只把它作为报告致命错误的一种方式。当某些不应该发生的场景发生时，我们就应该调用panic。

			一般而言，当panic异常发生时，程序会中断运行，
			并立即执行在该goroutine（可以先理解成线程，在中被延迟的函数（defer 机制）。
			随后，程序崩溃并输出日志信息。日志信息包括panic value和函数调用的堆栈跟踪信息。
		*/
	}
	//将json文件数据解析到struct中

	err = json.Unmarshal(data, &GlobalObject)
	// Unmarshal的第一个参数是json字符串，第二个参数是接受json解析的数据结构。
	//第二个参数必须是指针，否则无法接收解析的数据，如stu仍为空对象StuRead{}
	//Json Marshal：将数据编码成json字符串
	// Json Unmarshal：将json字符串解码到相应的数据结构
	if err != nil {
		panic(err)
	}
}

/*
	提供init方法，初始化GlobalObject这个全局对象

*/
func init() {

	//初始化GlobalObject变量，设置一些默认值
	GlobalObject = &GlobalObj{
		Name:          "ZinxServerApp",
		Version:       "V0.5",
		TcpPort:       8999,
		Host:          "0.0.0.0",
		MaxConn:       1000,
		MaxPacketSize: 4096, //4096=2的12次方，随便写的
	}

	//从conf/zinx.json配置文件中加载一些用户配置的参数
	// GlobalObject.Reload()
}
